package ita.class1.group2.supermarket.common.captain;

import ita.class1.group2.supermarket.common.captain.manager.ComponentManager;
import ita.class1.group2.supermarket.common.captain.manager.ControllerManager;
import ita.class1.group2.supermarket.common.util.ClassHelper;
import org.apache.log4j.Logger;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * CaptainApplication is the core of Captain and is used to manage all components of Captain
 *
 * @author Burgess Li
 * @date 2018/07/20
 */
public class CaptainApplication {

    public static final String MAIN_PACKAGE = "main-package";
    public static final String COMMON_PACKAGE = "common-package";

    private static final Logger logger = Logger.getLogger(CaptainApplication.class);
    private static CaptainApplication captainApplication = null;

    private ComponentManager componentManager = null;
    private ControllerManager controllerManager = null;
    private CaptainRouter captainRouter = null;

    private CaptainApplication() { }

    public static CaptainApplication getInstance() {
        if (captainApplication == null) {
            synchronized (CaptainApplication.class) {
                if (captainApplication == null)
                    captainApplication = new CaptainApplication();
            }
        }
        return captainApplication;
    }

    public void initializeCaptain(Map<String, String> initParams) {
        logger.info("Initialize captain application");
        if (initParams.containsKey(MAIN_PACKAGE)) {
            Set<Class<?>> classList = new HashSet<Class<?>>();
            classList.addAll(ClassHelper.getClzFromPkg(initParams.get(MAIN_PACKAGE)));
            classList.addAll(ClassHelper.getClzFromPkg(initParams.get(COMMON_PACKAGE)));
            this.componentManager = new ComponentManager(classList);
            this.controllerManager = new ControllerManager(classList);
            this.captainRouter = new CaptainRouter(controllerManager, componentManager);
            this.controllerManager.setCaptainRouter(captainRouter);
        }
    }

    public ControllerManager getControllerManager() {
        return controllerManager;
    }

    public ComponentManager getComponentManager() {
        return componentManager;
    }

}
